/*****************************************************************************************************************
* Class Name: NMRSLRProcessing
* Author: Accenture
* Date: 04-March-2012 
* Requirement/Project Name: NMR 
* Requirement Description: For standardizing the Standard Lead Request with data from MDM, CWS, Headings, and Do Not Call. 
*********************************************************************************************************************/

public class NMRSLRProcessing{

    /**
    * Method invoked from the trigger NMRSLRProcessingTrig for standardizing 
    * the Standardized Lead Request. Retrieves data from MDM, CWS, Headings and 
    * Do Not Call objects and then updates the SLR.
    */
    public static void slrStandardization(Map<Id, Standardized_Lead_Request__c> slrListMap){
        
        List<MDM_Listing_Matches__c> mdmList = new  List<MDM_Listing_Matches__c>();
        List<CWS_Account_Matches__c> cwsList = new List<CWS_Account_Matches__c>();
        Map<String, Standardized_Lead_Request__c> slrDNCMap = new Map<String, Standardized_Lead_Request__c>();
        Map<String, Standardized_Lead_Request__c> dncAddlPhone1Map = new Map<String, Standardized_Lead_Request__c>();
        Map<String, Standardized_Lead_Request__c> dncAddlPhone2Map = new Map<String, Standardized_Lead_Request__c>();
        Map<String, Standardized_Lead_Request__c> dncAddlPhone3Map = new Map<String, Standardized_Lead_Request__c>();
        Map<String, Standardized_Lead_Request__c> dncAddlPhone4Map = new Map<String, Standardized_Lead_Request__c>();
        Map<String, Standardized_Lead_Request__c> dncAddlPhone5Map = new Map<String, Standardized_Lead_Request__c>();
        
        //retrieving MDM data
        mdmList = [select Id, Name, Is_Matched__c, Contact_Email__c, YP_Id__c, Number_of_Employees__c, Phone__c,
                  Addl_Email_Addresses__c, URL__c, General_Description__c, Customer_Id__c, Pay_Free_Flag__c, 
                  Ad_Spending__c, Ad_Size__c, Hours__c, Chain_ID__c, AKAs__c, In_Business_Since__c, Service_Products__c, 
                  Source__c, Street_Address__c, City__c, State__c, Zip__c, Standardized_Lead_Request__r.Id, Business_Website_URL__c,
                  Business_Description__c  from MDM_Listing_Matches__c where Standardized_Lead_Request__r.Id in: slrListMap.keySet() 
                  and Is_Matched__c = true and  Standardized_Lead_Request__r.MDM_Failure__c = false];
        
        //retrieving CWS data
        cwsList = [select Id, Name, Is_Matched__c, Customer_Name__c, Phone_Number__c, Assigned_Rep_ATTUID__c, 
                  Customer_Id__c, Standardized_Lead_Request__r.Id from CWS_Account_Matches__c where Standardized_Lead_Request__r.Id in: slrListMap.keySet()
                  and Is_Matched__c = true];  
        
        
        if(mdmList.size() > 0)
            slrListMap = updateSLRWithMDM(slrListMap, mdmList); //updating SLR with MDM data
            
        if(cwsList.size() > 0)
            slrListMap = updateSLRWithCWS(slrListMap, cwsList); //updating SLR with CWS data
                
           
                
        createHeadings(slrListMap); //create Headings 
                         
        for(Standardized_Lead_Request__c slr : slrListMap.values()){
        
            //Update Company with Business Name
            if(NMRUtil.isEmpty(slr.Company__c))
                slr.Company__c = slr.Business_Name__c;
            
            //Update Business Name with Company
            else if(NMRUtil.isEmpty(slr.Business_Name__c))
                slr.Business_Name__c = slr.Company__c;
                
            //Update Lead Source Values 
            if('ASCP'.equalsIgnoreCase(slr.Lead_Source__c))
                slr.Lead_Source__c = 'AdStore';
            
            //Update Lead Type Values
            if ('Inquiry'.equalsIgnoreCase(slr.Lead_Type__c))
                slr.Lead_Type__c = 'Product Inquiry';
            else if ('Listing'.equalsIgnoreCase(slr.Lead_Type__c))
                slr.Lead_Type__c = 'Listing Creation';
            else if ('Inquiry+Listing'.equalsIgnoreCase(slr.Lead_Type__c))
                slr.Lead_Type__c = 'Product Inquiry + Listing Creation';
            else if ('IFIKI'.equalsIgnoreCase(slr.Lead_Type__c))
            {
                slr.Lead_Source__c = 'IFIKI';
                slr.Lead_Type__c = 'SFDC';
            }
            
            //Update Last Name if null
            if(NMRUtil.isEmpty(slr.Contact_Last_Name__c))
                slr.Contact_Last_Name__c = 'NA';
                
            //Update ASCP Account Email with Contact Email data
            if(!NMRUtil.isEmpty(slr.ASCP_Acct_Email__c))
                slr.Contact_Email__c = slr.ASCP_Acct_Email__c;
                            
            slr.Status__c = 'SLR Enrichment Completed'; //Set the status
                        
            slrDNCMap.put(NMRUtil.formatPhone(slr.Business_Phone__c), slr); // Map with Business Phone
            dncAddlPhone1Map.put(NMRUtil.formatPhone(slr.Additional_Phone_Number_1__c), slr); // Map with Additional Phone 1
            dncAddlPhone2Map.put(NMRUtil.formatPhone(slr.Additional_Phone_Number_2__c), slr); // Map with Additional Phone 2
            dncAddlPhone3Map.put(NMRUtil.formatPhone(slr.Additional_Phone_Number_3__c), slr); // Map with Additional Phone 3
            dncAddlPhone4Map.put(NMRUtil.formatPhone(slr.Additional_Phone_Number_4__c), slr); // Map with Additional Phone 4
            dncAddlPhone5Map.put(NMRUtil.formatPhone(slr.Additional_Phone_Number_5__c), slr); // Map with Additional Phone 5
        }
        //update the Do Not Call flag for all phone numbers
        doNotCallCheck(slrDNCMap, dncAddlPhone1Map, dncAddlPhone2Map, dncAddlPhone3Map, dncAddlPhone4Map, dncAddlPhone5Map); //Do Not Call check
        
    }
     
    
    /**
    * Method invoked for updating the Standardized Lead Request
    * with information from MDM Customer Matches.
    */
    private static Map<Id, Standardized_Lead_Request__c> updateSLRWithMDM(Map<Id, Standardized_Lead_Request__c> slrMap, List<MDM_Listing_Matches__c> mdmList){
        for (MDM_Listing_Matches__c mdm : mdmList){
           Standardized_Lead_Request__c slr = slrMap.get(mdm.Standardized_Lead_Request__r.Id);
                      
           //update the ASCP Account Email field
           if(!NMRUtil.isEmpty(mdm.Contact_Email__c))
                   slr.ASCP_Acct_Email__c = mdm.Contact_Email__c;
              
           //Append unique additional email-ids from MDM. Emails will be semi-colon seperated         
           if(!NMRUtil.isEmpty(mdm.Addl_Email_Addresses__c))
               {
                   List<String> slrEmailList = new List<String>();
                   List<String> mdmEmailList = mdm.Addl_Email_Addresses__c.split(';');
                   if(!NMRUtil.isEmpty(slr.Addl_Email_Addresses__c))
                       slrEmailList = slr.Addl_Email_Addresses__c.split(';');
                   if (!NMRUtil.isEmpty(slr.Contact_Email__c))
                       slrEmailList.add(slr.Contact_Email__c);
                   
                   for(Integer i=0; i<mdmEmailList.size() ; i++)
                   {
                       for(Integer j=0; j<slrEmailList.size(); j++)
                       {
                           if(mdmEmailList.size() > 0 && mdmEmailList[i].equals(slrEmailList[j]))
                           {
                               mdmEmailList.remove(i);
                               i--;
                               break; 
                           }
                       }
                   }
                   
                   String mdmEmails = '';
                   if(mdmEmailList.size() > 0){ 
                       Iterator<String> itr = mdmEmailList.Iterator();
                       while (itr.hasNext())
                           mdmEmails = mdmEmails + ';' + itr.next();
                   }
                   slr.Addl_Email_Addresses__c = slr.Addl_Email_Addresses__c + ';' + mdmEmails;
                   
                   if(slr.Addl_Email_Addresses__c.length() > 255)
                   {
                       slr.Addl_Email_Addresses__c = slr.Addl_Email_Addresses__c.subString(0,255);
                       Integer index = slr.Addl_Email_Addresses__c.lastIndexOf(';');
                       if(index != -1)
                           slr.Addl_Email_Addresses__c = slr.Addl_Email_Addresses__c.subString(0,index);
                   }        
                   
               }
               
               //Update the YP ID field    
               if(NMRUtil.isEmpty(slr.YP_Id__c) && !NMRUtil.isEmpty(mdm.YP_Id__c))
                   slr.YP_Id__c = mdm.YP_Id__c;

               //Update the Number of Employees
               if(!NMRUtil.isEmpty(mdm.Number_of_Employees__c))
                   slr.No_Of_Employee__c = mdm.Number_of_Employees__c;
               
               //Update the Customer Id
               if(NMRUtil.isEmpty(slr.Customer_ID__c) && null != mdm.Customer_Id__c)
                   slr.Customer_ID__c = mdm.Customer_Id__c;
               
               //Update the Pay Free flag
               if(!NMRUtil.isEmpty(mdm.Pay_Free_Flag__c))
                   slr.Pay_Free_Flag__c = mdm.Pay_Free_Flag__c;
               
               //Update the Ad Spending    
               if(!NMRUtil.isEmpty(mdm.Ad_Spending__c))
                   slr.Ad_Spending__c = mdm.Ad_Spending__c;
               
               //Update the Ad Size    
               if(!NMRUtil.isEmpty(mdm.Ad_Size__c))
                   slr.Ad_Size__c = mdm.Ad_Size__c;
               
               //Update the Hours Text    
               if(!NMRUtil.isEmpty(mdm.Hours__c))
                   slr.Business_Hours__c = mdm.Hours__c;
               
               //Update the General Description
               if(!NMRUtil.isEmpty(mdm.General_Description__c))
                   slr.General_Description__c = mdm.General_Description__c;
               
               //Update the URLs
               if(!NMRUtil.isEmpty(mdm.URL__c))
                   slr.URL__c = mdm.URL__c;
               
               //Update the Chain Id
               if(!NMRUtil.isEmpty(mdm.Chain_ID__c))
                   slr.Chain_ID__c = mdm.Chain_ID__c;
               
               //Update the AKAs
               if(!NMRUtil.isEmpty(mdm.AKAs__c))
                   slr.AKAs__c = mdm.AKAs__c;
               
               //Update the In Business Since
               if(!NMRUtil.isEmpty(mdm.In_Business_Since__c))
                   slr.In_Business_Since__c = mdm.In_Business_Since__c;
               
               //Update the Service Products
               if(!NMRUtil.isEmpty(mdm.Service_Products__c))
                   slr.Service_Products__c = mdm.Service_Products__c;
                   
               //Update the Business Website URL
               if(!NMRUtil.isEmpty(mdm.Business_Website_URL__c)){
                   if(NMRUtil.isEmpty(slr.Business_Website_URL__c))
                       slr.Business_Website_URL__c = mdm.Business_Website_URL__c;
                   else if (!slr.Business_Website_URL__c.equalsIgnoreCase(mdm.Business_Website_URL__c)){
                       String url = slr.Business_Website_URL__c + '; ' + mdm.Business_Website_URL__c;
                       
                       if(url.length() > 2000)
                       {
                           url = url.subString(0,2000);
                           Integer index = url.lastIndexOf(';');
                           if(index != -1)
                               url = url.subString(0,index);
                       }
                       
                       slr.Business_Website_URL__c = url;     
                   }
                   
               }
                   
               //Update the Business Description
               if(!NMRUtil.isEmpty(mdm.Business_Description__c)){
                   if(NMRUtil.isEmpty(slr.Business_Description__c))
                       slr.Business_Description__c = mdm.Business_Description__c;
                   else if (slr.Business_Description__c.length() != mdm.Business_Description__c.length()){
                       String busiDesc = slr.Business_Description__c + ' ' + mdm.Business_Description__c;
                       if(busiDesc.length() > 25000)
                           busiDesc = busiDesc.substring(0,25000);
                           
                       slr.Business_Description__c = busiDesc;      
                   }
               }
                   
               //Update the Source
               if(!NMRUtil.isEmpty(mdm.Source__c))
                   slr.Source__c = mdm.Source__c;
               
               //Update the Address details
               if(!NMRUtil.isEmpty(mdm.Street_Address__c))
                   slr.Address_Line__c = mdm.Street_Address__c;
                   
               if(!NMRUtil.isEmpty(mdm.City__c))
                   slr.City__c = mdm.City__c;
                   
               if(!NMRUtil.isEmpty(mdm.State__c))
                   slr.State__c = mdm.State__c;
                   
               if(!NMRUtil.isEmpty(mdm.Zip__c))
                   slr.Zip__c = mdm.Zip__c;
               
           }
           
        return slrMap;
    }
    
    
    /**
    * Method invoked for updating the Standardized Lead Request
    * with information from CWS Account Matches
    */
    private static Map<Id, Standardized_Lead_Request__c> updateSLRWithCWS(Map<Id, Standardized_Lead_Request__c> slrMap, List<CWS_Account_Matches__c> cwsList){
       for (CWS_Account_Matches__c cws : cwsList){
               
               Standardized_Lead_Request__c slr = slrMap.get(cws.Standardized_Lead_Request__r.Id);
               
               //Update the customer name
               if(!NMRUtil.isEmpty(cws.Customer_Name__c))
                   slr.Business_Name__c = cws.Customer_Name__c;
                   
                /** May be needed in future
               // Add additional phone number
               if(!NMRUtil.isEmpty(cws.Phone_Number__c)){
                   if(NMRUtil.isEmpty(slr.Business_Phone__c) || slr.Business_Phone__c.equals(cws.Phone_Number__c))
                       slr.Business_Phone__c = cws.Phone_Number__c;
                   else if (NMRUtil.isEmpty(slr.Additional_Phone_Number_1__c) || slr.Additional_Phone_Number_1__c.equals(cws.Phone_Number__c))
                       slr.Additional_Phone_Number_1__c = cws.Phone_Number__c; 
                   else if (NMRUtil.isEmpty(slr.Additional_Phone_Number_2__c) || slr.Additional_Phone_Number_2__c.equals(cws.Phone_Number__c))
                       slr.Additional_Phone_Number_2__c = cws.Phone_Number__c;
                   else if (NMRUtil.isEmpty(slr.Additional_Phone_Number_3__c) || slr.Additional_Phone_Number_3__c.equals(cws.Phone_Number__c))
                       slr.Additional_Phone_Number_3__c = cws.Phone_Number__c;
                   else if (NMRUtil.isEmpty(slr.Additional_Phone_Number_4__c) || slr.Additional_Phone_Number_4__c.equals(cws.Phone_Number__c))
                       slr.Additional_Phone_Number_4__c = cws.Phone_Number__c;
                   else if (NMRUtil.isEmpty(slr.Additional_Phone_Number_5__c) || slr.Additional_Phone_Number_5__c.equals(cws.Phone_Number__c))
                       slr.Additional_Phone_Number_5__c = cws.Phone_Number__c;
    
               }*/
               
               //Update the customer id
               if(!NMRUtil.isEmpty(cws.Customer_Id__c))
                   slr.Customer_ID__c =  cws.Customer_Id__c;
               
               //Updating the Assigned Rep ATTUID              
               if(!NMRUtil.isEmpty(cws.Assigned_Rep_ATTUID__c))
                   slr.ATTUID__c = cws.Assigned_Rep_ATTUID__c;
           
       }
       return slrMap;
    
    }
    
    /**
    * Method invoked for updating the Do Not Call Flag on the 
    * Standardized Lead Request if the Phone Number is present
    * in the Do Not Call table.
    */
    private static void doNotCallCheck(Map<String, Standardized_Lead_Request__c> slrDNCMap, Map<String, Standardized_Lead_Request__c> dncAddlPhone1Map, 
    Map<String, Standardized_Lead_Request__c> dncAddlPhone2Map, Map<String, Standardized_Lead_Request__c> dncAddlPhone3Map, 
    Map<String, Standardized_Lead_Request__c> dncAddlPhone4Map, Map<String, Standardized_Lead_Request__c> dncAddlPhone5Map)
    {
        Map<String, Standardized_Lead_Request__c> dncTotalMap = new Map<String, Standardized_Lead_Request__c>();
        
        dncTotalMap.putAll(slrDNCMap);
        dncTotalMap.putAll(dncAddlPhone1Map);
        dncTotalMap.putAll(dncAddlPhone2Map);
        dncTotalMap.putAll(dncAddlPhone3Map);
        dncTotalMap.putAll(dncAddlPhone4Map);
        dncTotalMap.putAll(dncAddlPhone5Map);
        
        //retrieve Active Do Not Call numbers
        List<Do_Not_Call__c> dncNumbers = [select Id, Phone_Number__c from Do_Not_Call__c where Phone_Number__c in: dncTotalMap.keySet() and Active__c = True];
        
        for(Do_Not_Call__c dnc : dncNumbers)
        {
            Standardized_Lead_Request__c slr = new Standardized_Lead_Request__c();
            
            if(slrDNCMap.containsKey(dnc.Phone_Number__c)){
                slr = slrDNCMap.get(dnc.Phone_Number__c);
                slr.On_Do_Not_Call_List__c = true;
            }
            if(dncAddlPhone1Map.containsKey(dnc.Phone_Number__c)){
                slr = dncAddlPhone1Map.get(dnc.Phone_Number__c);
                slr.Do_Not_Call_1__c = true;
            }
            if(dncAddlPhone2Map.containsKey(dnc.Phone_Number__c)){
                slr = dncAddlPhone2Map.get(dnc.Phone_Number__c);
                slr.Do_Not_Call_2__c = true;
            }
            if(dncAddlPhone3Map.containsKey(dnc.Phone_Number__c)){
                slr = dncAddlPhone3Map.get(dnc.Phone_Number__c);
                slr.Do_Not_Call_3__c = true;
            }
            if(dncAddlPhone4Map.containsKey(dnc.Phone_Number__c)){
                slr = dncAddlPhone4Map.get(dnc.Phone_Number__c);
                slr.Do_Not_Call_4__c = true;
            }
            if(dncAddlPhone5Map.containsKey(dnc.Phone_Number__c)){
                slr = dncAddlPhone5Map.get(dnc.Phone_Number__c);
                slr.Do_Not_Call_5__c = true;
            }
        }    
    }
    
    
    /**
    * Method invoked for creating unique Headings on the 
    * Standardized Lead Request. Headings are picked from Original
    * Lead Request and MDM Customer Information
    */
    private static void createHeadings(Map<Id, Standardized_Lead_Request__c> slrMap){

    Map <String, Cate__c> olrHeadingMap = new Map<String, Cate__c>();
    Map <String, Cate__c> mdmHeadingMap = new Map<String, Cate__c>();
    Map <String, Cate__c> slrHeadingMap = new Map<String, Cate__c>();
    Map <String, Cate__c> newHeadingsMap = new Map<String, Cate__c>();
    
    Map <Id, Map<String, Cate__c>> olrHeadingDoubleMap = new Map<Id, Map<String, Cate__c>>();
    Map <Id, Map<String, Cate__c>> slrHeadingDoubleMap = new Map<Id, Map<String, Cate__c>>();
    Map <Id, Map<String, Cate__c>> mdmHeadingDoubleMap = new Map<Id, Map<String, Cate__c>>();
    list<Cate__c> headingsList = new list<Cate__c>();
    list<Cate__c> newHeadingsList = new list<Cate__c>();
    
    for(Cate__c heading: [select Id, Description__c, Heading_Code__c, Restricted_Flag__c, Source__c, 
                    Weight__c, YP_Cat__c, Source_Lead_I__c, Original_Lead_Request__r.Standardized_Lead_Request__r.Id from Cate__c 
                    where Original_Lead_Request__r.Standardized_Lead_Request__r.Id in : slrMap.keySet() order by CreatedDate]){
        olrHeadingMap.put(heading.YP_Cat__c, heading);
        olrHeadingDoubleMap.put(heading.Original_Lead_Request__r.Standardized_Lead_Request__r.Id, olrHeadingMap);  
    }
    
    for(Cate__c heading: [select Id, Description__c, Heading_Code__c, Restricted_Flag__c, Source__c, 
                    Weight__c, YP_Cat__c, Source_Lead_I__c, MDM_Listing_Matches__r.Standardized_Lead_Request__r.Id from Cate__c 
                    where MDM_Listing_Matches__r.Standardized_Lead_Request__r.Id in : slrMap.keySet() and MDM_Listing_Matches__r.Is_Matched__c = true order by CreatedDate]){
        mdmHeadingMap.put(heading.YP_Cat__c, heading);
        mdmHeadingDoubleMap.put(heading.MDM_Listing_Matches__r.Standardized_Lead_Request__r.Id, mdmHeadingMap);    
    }
    
    for(Cate__c heading: [select Id, YP_Cat__c, Standardized_Lead_Request__r.Id from Cate__c 
                    where Standardized_Lead_Request__r.Id in : slrMap.keySet() order by CreatedDate]){
        slrHeadingMap.put(heading.YP_Cat__c, heading);
        slrHeadingDoubleMap.put(heading.Standardized_Lead_Request__r.Id, slrHeadingMap);  
    }
    
    for(Id slrId: slrHeadingDoubleMap.keySet()){
         if(olrHeadingDoubleMap.containsKey(slrId)){
             for(String ypCatId : slrHeadingDoubleMap.get(slrId).keySet()){
                 if(olrHeadingDoubleMap.get(slrId).containsKey(ypCatId)){
                     olrHeadingDoubleMap.get(slrId).remove(ypCatId);    
                 }            
             }            
         }
         if(mdmHeadingDoubleMap.containsKey(slrId)){
             for(String ypCatId : slrHeadingDoubleMap.get(slrId).keySet()){
                 if(mdmHeadingDoubleMap.get(slrId).containsKey(ypCatId)){
                     mdmHeadingDoubleMap.get(slrId).remove(ypCatId);    
                 }            
             }            
         }
    }
    
    for(Id mdmId: mdmHeadingDoubleMap.keySet()){
         if(olrHeadingDoubleMap.containsKey(mdmId)){
             for(String ypCatId : mdmHeadingDoubleMap.get(mdmId).keySet()){
                 if(olrHeadingDoubleMap.get(mdmId).containsKey(ypCatId)){
                     olrHeadingDoubleMap.get(mdmId).remove(ypCatId);    
                 }            
             }            
         }
    }
         
    for(Id slrId: mdmHeadingDoubleMap.keySet()){
        for(Cate__c heading : mdmHeadingDoubleMap.get(slrId).values()){
            Cate__c newHeading = new Cate__c();
            newHeading.Description__c = heading.Description__c;
            newHeading.Heading_Code__c = heading.Heading_Code__c;
            newHeading.Restricted_Flag__c = heading.Restricted_Flag__c;
            newHeading.Source__c = heading.Source__c;
            newHeading.Source_Lead_I__c = heading.Source_Lead_I__c;
            newHeading.Weight__c = heading.Weight__c;
            newHeading.YP_Cat__c = heading.YP_Cat__c;
            newHeading.Standardized_Lead_Request__c = slrId;
            if(newHeading.Weight__c == 1){
                slrMap.get(slrId).Weight_Check_from_heading__c = True;
            }
            newHeadingsList.add(newHeading);
        }
    }
    
    for(Id slrId: olrHeadingDoubleMap.keySet()){
        for(Cate__c heading : olrHeadingDoubleMap.get(slrId).values()){
            Cate__c newHeading = new Cate__c();
            newHeading.Description__c = heading.Description__c;
            newHeading.Heading_Code__c = heading.Heading_Code__c;
            newHeading.Restricted_Flag__c = heading.Restricted_Flag__c;
            newHeading.Source__c = heading.Source__c;
            newHeading.Source_Lead_I__c = heading.Source_Lead_I__c;
            newHeading.Weight__c = heading.Weight__c;
            newHeading.YP_Cat__c = heading.YP_Cat__c;
            newHeading.Standardized_Lead_Request__c = slrId;
            if(newHeading.Weight__c == 1){
                slrMap.get(slrId).Weight_Check_from_heading__c = True;
            }
            newHeadingsList.add(newHeading);
        }
    }
    
    //inserting the Headings
    try{
    if(newHeadingsList.size() > 0)
        insert newHeadingsList;
    } catch(DMLException e){
        system.debug('DML Exception while creating Headings: ' + e.getMessage());
    }

    }

}